/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

package Beans.Requests.MediumManagement;

import Utilities.Constants;
import Utilities.Functions;
import Utilities.PermissionsConstants;
import org.virtualbox_3_2.DeviceType;
import org.virtualbox_3_2.MediumType;

/**
 * Instances of this class are used by the user interface when a request to
 * modify a medium is sent to the media management service.
 *
 * @author Angel Sanadinov
 */
public class ModifyMediumRequest extends MediumManagementRequest
{
    private String description;         //new description for the medium
    private String location;            //new location for the medium (may be n/a)
    private MediumType type;            //new medium type
    private boolean autoReset;          //differencing medium, auto-reset status
    private int newOwnerId;             //new owner id
    private String permissions;         //new permissions
    private DeviceType deviceType;      //medium's device type

    private boolean isDescriptionSet;   //denotes whether a new description is set
    private boolean isLocationSet;      //denotes whether a new location is set
    private boolean isTypeSet;          //denotes whether a new type is set
    private boolean isAutoResetSet;     //denotes the auto-reset status
    private boolean arePermissionsSet;  //denotes whether new permissions are set
    private boolean isNewOwnerIdSet;    //denotes whether a new owner is set

    /**
     * No-argument constructor. <br><br>
     * All fields are set to their invalid values.
     *
     * @see Constants#INVALID_USER_ID
     */
    public ModifyMediumRequest()
    {
        setRequestedAction(PermissionsConstants.ACTION_MEDIUM_MODIFY);
        this.description = null;
        this.location = null;
        this.type = null;
        this.autoReset = false;
        this.newOwnerId = Constants.INVALID_USER_ID;

        this.isDescriptionSet = false;
        this.isLocationSet = false;
        this.isTypeSet = false;
        this.isAutoResetSet = false;
        this.arePermissionsSet = false;
        this.isNewOwnerIdSet = false;
    }

    /**
     * Constructs a "modify medium" request with the specified data. <br><br>
     *
     * <b>Note:</b> <i>All data to be modified should be explicitly set!</i>
     *
     * @param requestorId the id of the user that made the request
     * @param serverId the id of the server on which the medium resides
     * @param mediumId the id of the medium that will be modified
     * @param deviceType the device type of the medium
     */
    public ModifyMediumRequest(int requestorId, int serverId, String mediumId, DeviceType deviceType)
    {
        this();
        setRequestorId(requestorId);
        setServerId(serverId);
        setMediumId(mediumId);
        setRequestedAction(PermissionsConstants.ACTION_MEDIUM_MODIFY);
        this.deviceType = deviceType;
    }

    /**
     * Retrieves the description of the medium.
     *
     * @return the medium description
     */
    public String getDescription()
    {
        return description;
    }

    /**
     * Retrieves the location of the medium on the host.
     *
     * @return the medium location
     */
    public String getLocation()
    {
        return location;
    }

    /**
     * Retrieves the type of the medium.
     *
     * @return the medium type
     */
    public MediumType getType()
    {
        return type;
    }

    /**
     * Retrieves the auto-reset flag of the medium. <br><br>
     *
     * <b>Note:</b> <i>For differencing disks only.</i>
     *
     * @return <code>true</code> if the medium is set to reset on each machine power up
     */
    public boolean getAutoReset()
    {
        return autoReset;
    }

    /**
     * Retrieves the id of the new medium owner.
     *
     * @return the new owner id
     */
    public int getNewOwnerId()
    {
        return newOwnerId;
    }

    /**
     * Retrieves the new permissions of the medium.
     *
     * @return the medium's permissions
     */
    public String getPermissions()
    {
        return permissions;
    }

    /**
     * Retrieves the medium's device type.
     *
     * @return the device type
     */
    public DeviceType getDeviceType()
    {
        return deviceType;
    }

    /**
     * Returns whether a description was set.
     *
     * @return <code>true</code> if a description was set or <code>false</code> otherwise
     */
    public boolean isDescriptionSet()
    {
        return isDescriptionSet;
    }

    /**
     * Returns whether a location was set.
     *
     * @return <code>true</code> if a location was set or <code>false</code> otherwise
     */
    public boolean isLocationSet()
    {
        return isLocationSet;
    }

    /**
     * Returns whether a medium device type was set.
     *
     * @return <code>true</code> if a device type was set or <code>false</code> otherwise
     */
    public boolean isTypeSet()
    {
        return isTypeSet;
    }

    /**
     * Returns whether auto-reset was set.
     *
     * @return <code>true</code> if auto-reset was set or <code>false</code> otherwise
     */
    public boolean isAutoResetSet()
    {
        return isAutoResetSet;
    }

    /**
     * Returns whether permissions were set.
     *
     * @return <code>true</code> if permissions were set or <code>false</code> otherwise
     */
    public boolean arePermissionsSet()
    {
        return arePermissionsSet;
    }

    /**
     * Returns whether a new owner id was set.
     *
     * @return <code>true</code> if a new owner id was set or <code>false</code> otherwise
     */
    public boolean isNewOwnerIdSet()
    {
        return isNewOwnerIdSet;
    }

    /**
     * Sets the description of the medium.
     *
     * @param description the medium description
     */
    public void setDescription(String description)
    {
        this.description = description;
        this.isDescriptionSet = true;
    }

    /**
     * Sets the location of the medium on the host.
     *
     * @param location the medium location
     */
    public void setLocation(String location)
    {
        this.location = location;
        this.isLocationSet = true;
    }

    /**
     * Sets the type of the medium.
     *
     * @param type the medium type
     */
    public void setType(MediumType type)
    {
        this.type = type;
        this.isTypeSet = true;
    }

    /**
     * Sets the auto-reset feature of the medium. <br><br>
     *
     * <b>Note:</b> <i>For differencing disks only.</i>
     *
     * @param autoReset set to <code>true</code> if the disk should automatically
     *                  reset on machine power up
     */
    public void setAutoReset(boolean autoReset)
    {
        this.autoReset = autoReset;
        this.isAutoResetSet = true;
    }

    /**
     * Sets the new permissions data
     *
     * @param permissions the permissions data
     */
    public void setPermissions(String permissions)
    {
        this.permissions = permissions;
        this.arePermissionsSet = true;
    }

    /**
     * Sets the id of the new owner.
     *
     * @param newOwnerId the new owner id
     */
    public void setNewOwnerId(int newOwnerId)
    {
        this.newOwnerId = newOwnerId;
        this.isNewOwnerIdSet = true;
    }

    /**
     * Sets the medium device type.
     *
     * @param device the device type
     */
    public void setDeviceType(DeviceType device)
    {
        this.deviceType = device;
    }

    @Override
    public boolean isValid()
    {
        if(super.isValid() && isMediumIdValid() && deviceType != null &&
                (deviceType == DeviceType.HARD_DISK || deviceType == DeviceType.DVD || deviceType == DeviceType.FLOPPY)
                && ((isDescriptionSet && description != null) || (isLocationSet && location != null)
                || (isTypeSet && type != null) || isAutoResetSet
                || (arePermissionsSet && Functions.arePermissionsValid(permissions))
                || (isNewOwnerIdSet && Functions.isUserIdValid(newOwnerId))))
            return true;
        else
            return false;
    }

    /**
     * Returns a textual representation of the object. <br>
     *
     * It is in the form: "ClassName: (mediumId,description,location,type,autoReset,
     * newOwnerId,permissions,deviceType)".
     *
     * @return the object represented as a String
     */
    @Override
    public String toString()
    {
        return ModifyMediumRequest.class.getSimpleName()
                + ": (" + getMediumId() + "," + description + "," + location
                + "," + type + "," + autoReset + "," + newOwnerId
                + "," + permissions + "," + deviceType + ")";
    }
}
